from flask import Flask, request, jsonify
import random

app = Flask(__name__)


@app.route('/table_to_rota', methods=['POST'])
def table_to_rota():
    # 接收并解析前端发送的JSON数据
    received_data = request.get_json()
    if not received_data or 'classes' not in received_data or 'num' not in received_data or 'data' not in received_data:
        return jsonify({"错误": "数据格式无效"}), 400

    try:
        max_duty_count = received_data['classes']
        max_duty_per_period = received_data['num']
        schedules = received_data['data']
    except Exception as e:
        return jsonify({"错误": f"处理数据时出错： {str(e)}"}), 500

    # 获取每节课没有可的学生
    free_students = [[[] for _ in range(5)] for _ in range(5)]

    for day in range(5):
        for period in range(5):
            duty_students = []
            for student, schedule in schedules.items():
                if schedule[day][period] == "":
                    # 这个位置[period][day]的相反，导致了后面的表全都拧吧的难受
                    duty_students.append(student)
                free_students[day][period] = duty_students

    # 初始化值班表
    duty_table = [[[] for _ in range(5)] for _ in range(5)]
    student_duty_count = {student: 0 for student in schedules}  # 记录每个学生已值班的次数

    # 先迁就没课的学生少的时间段的课程
    # 获取每个三维数组的位置信息和长度
    array_info = [(i, j, len(sublist)) for i, row in enumerate(free_students) for j, sublist in enumerate(row)]
    # 按照子数组长度由短到长排序
    sorted_array_info = sorted(array_info, key=lambda x: x[2])

    for day, period, length in sorted_array_info:
        # 在这里处理子数组，i是行号，j是列号
        # print(f"星期 {day + 1}, 第 {period + 1} 节课 长度 {length}: {free_students[day][period]}")
        duty_students = []
        cont = 0
        while len(duty_students) < max_duty_per_period and len(free_students[day][period]) > 0:
            # 添加条件判断，避免空列表的情况
            if free_students[day][period]:
                student = random.choice(free_students[day][period])
                if student_duty_count[student] < max_duty_count:
                    # 将学生名字插入到这节课的值班列表中
                    duty_students.append(student)

                    # 学生值班次数+1
                    student_duty_count[student] += 1

                    # 在每节课没课列表中对应的位置，删掉这个同学的名字
                    free_students[day][period].remove(student)

                    # 在读取到的学生基本数据中，将这节课改为“有”
                    schedules[student][period][day] = '有'
                    # print(schedules[student][period][day], '---', student, '对应的课', '星期', day + 1, '  第', period + 1, '节课')

                elif len(free_students[day][period]) <= 1:
                    break

            else:
                print("没有可以值班的学生了，跳过")
                print(len(duty_students) < max_duty_per_period, len(free_students[day][period]))
                cont += 1
                if cont > 50:
                    break
        duty_table[day][period] = duty_students

    while True:
        cont = 0
        record = 0
        for student in schedules:
            if student_duty_count[student] < max_duty_count:
                print(f"{student} 同学以值班 {student_duty_count[student]} 次")
                record = 1
        if record == 1:
            print("其余同学值班次数均以达到设置的值班次数")
        else:
            print("所有同学值班次数均以达到设置的值班次数")
        print('------------------------------------------------------')
        for student in schedules:
            if student_duty_count[student] < max_duty_count:
                cont += 1

                # 获取当前学生的课表
                student_schedule = schedules[student]

                # 找到没有课的位置
                empty_slots = [(i, j) for i in range(len(student_schedule)) for j in range(len(student_schedule[i])) if
                               student_schedule[i][j] == '']
                selected_slot = random.choice(empty_slots)
                # print( selected_slot)
                period, day = selected_slot
                print(student, '-----', '星期', day + 1, ' 第', period + 1, "节没课，以成排入排值班表")

                # 向值班表中插入新的名字
                duty_table[period][day].append(student)

                # 在读取到的学生基本数据中，将这节课改为“有”
                schedules[student][period][day] = '有'

                # 学生值班次数+1
                student_duty_count[student] += 1
        if cont == 0:
            break
    print('------------------------------------------------------')

    # duty_table = new_duty_table
    print("打印最终值班表")
    for row in duty_table:
        print(row)

    return jsonify(duty_table)


if __name__ == '__main__':
    app.run(host="127.0.0.1", port=5000, debug=True)
